package com.zy.design.state.table;

/**
 * @author zhaoyi
 * @date 2021/9/23 10:46
 * 查表法的状态机
 *
 * 较复杂的状态机，包含的状态比较多，但是没太多的其他复杂业务逻辑操作数据库等.
 */
public class MarioStateMachine {

    //得分
    private int score;

    //当前状态
    private StateEnum status;

    public MarioStateMachine() {
        this.score = 0;
        this.status = StateEnum.SMALL;
    }

    public MarioStateMachine(int score, StateEnum status) {
        this.score = score;
        this.status = status;
    }

    //吃蘑菇
    public void eatMustRoom() {
        event(EventEnum.GOT_MUSHROOM);
    }

    //获得斗篷
    public void eatCape() {
        event(EventEnum.GOT_CAPE);
    }

    //获得火焰
    public void eatFire() {
        event(EventEnum.GOT_FIRE);
    }

    //遇怪
    public void monster() {
        event(EventEnum.MET_MONSTER);
    }


    /**
     * 构建状态表
     * -------------------------------------------------------------------------------------------------
     * | 	       |GOT_MUSHROOM (吃蘑菇) | GOT_CAPE(获得斗篷) | GOT_FIRE(获得火焰) | MET_MONSTER(遇怪) |
     * |  SMALL   |    SUPER/+100        |    CAPE /+200      |     FIRE/+300      |       /           |
     * |  SUPER   |       /              |    CAPE /+200      |     FIRE/+300      |   SMALL/-100      |
     * |  CAPE    |       /              |        /           |        /           |   SMALL/-200      |
     * |  FIRE    |       /              |        /           |        /           |   SMALL/-300      |
     * -------------------------------------------------------------------------------------------------
     */
    private final StateEnum[][] transitionTable = {
            {StateEnum.SUPER, StateEnum.CAPE, StateEnum.FIRE, StateEnum.SMALL},
            {StateEnum.SUPER, StateEnum.CAPE, StateEnum.FIRE, StateEnum.SMALL},
            {StateEnum.CAPE, StateEnum.CAPE, StateEnum.CAPE, StateEnum.SMALL},
            {StateEnum.FIRE, StateEnum.FIRE, StateEnum.FIRE, StateEnum.SMALL}
    };
    private final int[][] scoreTable = {
            {+100, +200, +300, 0},
            {0, +200, +300, -100},
            {0, 0, 0, -200},
            {0, 0, 0, -300}
    };
    private void event(EventEnum event) {
        this.score = this.score + scoreTable[this.status.getY()][event.getX()];
        this.status = transitionTable[this.status.getY()][event.getX()];
    }


    @Override
    public String toString() {
        return "MarioStateMachine{" +
                "score=" + score +
                ", status=" + status +
                '}';
    }
}
